/**
 * @Author       : Hejh(3010733382@qq.com)
 * @Version      : V1.0
 * @Date         : 2024-01-15 18:55:18
 * @Description  : 常见数据库字段验证的汇总
 */

const { Op } = require('sequelize')
const { ERROR_USER_CODE } = require('@/constants/errorCode')
const { User, Exam, Chapter, Paper, Question } = require('@/models/model')
const R = require('@/models/Response')

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 根据模型的不同返回新的函数，验证模型ID数组合法性
 * @param {*} model 数据库实体模型
 * @returns {Function} 新的函数，验证模型ID数组合法性
 */
const idsCheck = (model) => {
  return async (ids, ingoreRootId = false, options = []) => {
    let newIds = [...new Set(ids)]
    // 不能出现重复的
    if (newIds.length !== ids.length) {
      return false
    }

    if (ingoreRootId) {
      newIds = newIds.filter((item) => +item !== -1)
    }

    if (newIds.length === 0) {
      return true
    }

    newIds = newIds.map((item) => BigInt(item))

    // 查看不重复的和数据库的是否对的上
    const myWhere = {
      id: {
        [Op.in]: newIds
      }
    }
    for (let i = 0; i < options.length; i++) {
      let opt = options[i]
      myWhere[opt.field] = opt.value
    }

    const idModels = await model.findAll({
      where: myWhere
    })

    if (idModels.length !== newIds.length) {
      return false
    }

    return true
  }
}

/**
 * @author: Hejh(3010733382@qq.com)
 * @description: 根据模型的不同返回新的函数，验证模型名称数组合法性
 * @param {*} model 数据库实体模型
 * @param {string} fieldName 要验证的名称字段,默认为'name'
 * @returns {Function} 新的函数，验证名称数组的合法性
 */
const nameCheck = (model, fieldName = 'name') => {
  return async (name) => {
    const nameValidate = await model.findOne({
      where: {
        [fieldName]: name
      }
    })
    if (nameValidate) {
      return false
    }
    return true
  }
}

const dumpCheck = {
  /**
   * 校验用户名是否重复
   * @param {*} ctx
   * @param {string} username
   * @returns {Promise<boolean>}
   */
  checkUsername: async (ctx, username) => {
    if (!username) {
      return true
    }

    const usernameValidate = await User.findOne({
      where: {
        username
      },
      attributes: ['id']
    })
    if (usernameValidate) {
      ctx.body = R.error(ERROR_USER_CODE.USERNAME_DUMP_ERROR)
      return false
    }

    return true
  },

  /**
   * 检验手机号是否被占用
   * @param {*} ctx
   * @param {string} phone
   * @returns {Promise<boolean>}
   */
  checkPhone: async (ctx, phone) => {
    if (!phone) {
      return true
    }

    const user = await User.findOne({
      where: {
        phone
      },
      attributes: ['id']
    })
    if (user) {
      ctx.body = R.error(ERROR_USER_CODE.PHONE_DUMP_ERROR)
      return false
    }

    return true
  },

  /**
   * 检验邮箱是否被占用
   * @param {*} ctx
   * @param {string} email
   * @returns {Promise<boolean>}
   */
  checkEmail: async (ctx, email) => {
    if (!email) {
      return true
    }

    const user = await User.findOne({
      where: {
        email
      },
      attributes: ['id']
    })
    if (user) {
      ctx.body = R.error(ERROR_USER_CODE.EMAIL_DUMP_ERROR)
      return false
    }

    return true
  },

  /**
   * @author: Hejh(3010733382@qq.com)
   * @description: 验证考试ID是否正确
   * @param {array<string>} examIds 考试ID数组
   * @returns {Promise<boolean>}
   */
  checkExamIds: idsCheck(Exam),

  /**
   * @author: Hejh(3010733382@qq.com)
   * @description: 用户ID的合法性校验
   * @param {array<string>} userIds 用户ID数组
   * @returns {Promise<boolean>}
   */
  checkUserIds: idsCheck(User),

  /**
   * @author: Hejh(3010733382@qq.com)
   * @description: 验证章节ID数组的合法性
   * @param {array<string>} chapterIds 章节ID数组
   * @returns {Promise<boolean>}
   */
  checkChapterIds: idsCheck(Chapter),

  /**
   * @author: Hejh(3010733382@qq.com)
   * @description: 验证试卷ID数组的合法性
   * @param {array<string>} paperIds 试卷ID数组
   * @returns {Promise<boolean>}
   */
  checkPaperIds: idsCheck(Paper),

  /**
   * @author: Hejh(3010733382@qq.com)
   * @description: 验证题目ID数组的合法性
   * @param {array<string>} paperIds 题目ID数组
   * @returns {Promise<boolean>}
   */
  checkQuestionIds: idsCheck(Question)
}

module.exports.dumpCheck = dumpCheck
